package com.nit.bike.utils;

import com.nit.bike.dto.system.TokenDTO;
import com.nit.bike.dto.utils.OpResultDTO;
import com.nit.bike.dto.utils.PagingDTO;
import com.nit.bike.dto.utils.TableRspDTO;

import java.util.ArrayList;

/**
 * 接口权限验证
 */
public class AuthorizationUtil {
    public enum Accessible {
        // 能够访问
        ABLE,
        // token信息有误
        TOKEN,
        // 权限有误
        POWER,
    }

    /**
     * 仅限管理员访问的接口
     */
    public static Accessible adminInterface(String token) {
        TokenDTO tokenDTO = JWTUtil.verifyToken(token);
        Accessible accessible;
        if (tokenDTO == null) {
            accessible = Accessible.TOKEN;
        } else {
            if (tokenDTO.getRoleId() != 1) {
                accessible = Accessible.POWER;
            } else {
                accessible = Accessible.ABLE;
            }
        }
        return accessible;
    }

    /**
     * 仅限管理员访问的接口
     * 仅返回能否访问
     */
    public static boolean adminInterfaceBool(String token) {
        return adminInterface(token) == Accessible.ABLE;
    }

    /**
     * 仅限管理员访问的接口
     * 仅返回能否访问
     * 同时设置OpResult
     */
    public static boolean adminInterfaceBool(String token, OpResultDTO op) {
        Accessible accessible = adminInterface(token);
        setOpResult(accessible, op);
        return accessible == Accessible.ABLE;
    }

    /**
     * 仅限管理员访问的接口
     * 仅返回能否访问
     * 同时设置TableRsp
     */
    public static boolean adminInterfaceBool(String token, TableRspDTO rsp) {
        Accessible accessible = adminInterface(token);
        setTableRsp(accessible, rsp);
        return accessible == Accessible.ABLE;
    }

    /**
     * 管理员和用户本人能够访问的接口
     */
    public static Accessible adminAndSelf(String token, Long userId) {
        TokenDTO tokenDTO = JWTUtil.verifyToken(token);
        Accessible accessible;
        if (tokenDTO == null) {
            accessible = Accessible.TOKEN;
        } else {
            if (tokenDTO.getRoleId() != 1 && !tokenDTO.getAccountId().equals(userId)) {
                accessible = Accessible.POWER;
            } else {
                accessible = Accessible.ABLE;
            }
        }
        return accessible;
    }

    /**
     * 管理员和用户本人能够访问的接口
     * 仅返回能否访问
     */
    public static boolean adminAndSelfBool(String token, Long userId) {
        return adminAndSelf(token, userId) == Accessible.ABLE;
    }

    /**
     * 管理员和用户本人能够访问的接口
     * 仅返回能否访问
     * 同时设置OpResult
     */
    public static boolean adminAndSelfBool(String token, Long userId, OpResultDTO op) {
        Accessible accessible = adminAndSelf(token, userId);
        setOpResult(accessible, op);
        return accessible == Accessible.ABLE;
    }

    /**
     * 管理员和用户本人能够访问的接口
     * 仅返回能否访问
     * 同时设置TableRsp
     */
    public static boolean adminAndSelfBool(String token, Long userId, TableRspDTO rsp) {
        Accessible accessible = adminAndSelf(token, userId);
        setTableRsp(accessible, rsp);
        return accessible == Accessible.ABLE;
    }

    /**
     * 登录用户访问的接口
     */
    public static Accessible userInterface(TokenDTO tokenDTO) {
        Accessible accessible;
        if (tokenDTO == null) {
            accessible = Accessible.TOKEN;
        } else {
            if (tokenDTO.getAccountId() == null || tokenDTO.getAccountId() < 1) {
                accessible = Accessible.POWER;
            } else {
                accessible = Accessible.ABLE;
            }
        }
        return accessible;
    }

    /**
     * 登录用户访问的接口
     * 仅返回能否访问
     */
    public static boolean userInterfaceBool(TokenDTO tokenDTO) {
        return userInterface(tokenDTO) == Accessible.ABLE;
    }

    /**
     * 登录用户访问的接口
     * 仅返回能否访问
     * 同时设置OpResult
     */
    public static boolean userInterfaceBool(TokenDTO tokenDTO, OpResultDTO op) {
        Accessible accessible = userInterface(tokenDTO);
        setOpResult(accessible, op);
        return accessible == Accessible.ABLE;
    }

    /**
     * 管理员和用户本人能够访问的接口
     * 仅返回能否访问
     * 同时设置TableRsp
     */
    public static boolean userInterfaceBool(TokenDTO tokenDTO, TableRspDTO rsp) {
        Accessible accessible = userInterface(tokenDTO);
        setTableRsp(accessible, rsp);
        return accessible == Accessible.ABLE;
    }

    /**
     * 设置OpResult
     */
    public static void setOpResult(Accessible accessible, OpResultDTO op) {
        switch (accessible) {
            case TOKEN:
                op.setMessage("error");
                op.setResult("用户信息有误");
                break;
            case POWER:
                op.setMessage("error");
                op.setResult("用户权限有误");
                break;
        }
    }

    /**
     * 设置TableRsp
     */
    public static void setTableRsp(Accessible accessible, TableRspDTO rsp) {
        switch (accessible) {
            case TOKEN:
                rsp.setMessage("用户信息有误");
                break;
            case POWER:
                rsp.setMessage("用户权限有误");
                break;
        }
        PagingDTO pagingDTO = new PagingDTO(
                1,
                10,
                0L,
                new ArrayList<>()
        );
        rsp.setResult(pagingDTO);
        rsp.setStatus(200);
        rsp.setTimestamp(System.currentTimeMillis());
    }
}
